﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;

namespace PdfLibrary
{
    public class PdfStream : IPdfObject
    {
        public PdfDictionary dictionary = null;
        public byte[] streamData;

        public bool LoadFromReader(PdfReader reader, bool throwException)
        {
            if (reader.ReadWord() != "stream")
                if (throwException) throw new PdfParsingException(reader, "PdfStream: 'stream' start tag not found!");
                else return false;

            if (this.dictionary == null)
                throw new PdfParsingException(reader, "PdfStream dictionary not set!");

            var lengthObj = this.dictionary["Length"];
            if (lengthObj is PdfIndirectReference)
                lengthObj = ((PdfIndirectReference)lengthObj).ResolvedObject;

            int length = (int)((PdfNumber)lengthObj).value;
            reader.SkipNewLineCharacters();
            this.streamData = reader.ReadStream(length);

            if (!reader.TryReadToken("endstream"))
                throw new PdfParsingException(reader, "PdfStream: 'endstream' end tag not found!");

            return true;
        }

        public Stream DecodedStream
        {
            get
            {
                Stream src = new MemoryStream(this.streamData);

                IPdfObject filter;
                if (this.dictionary.TryGetValue("Filter", out filter))
                    switch (((PdfName)filter).Value)
                    {
                        case "FlateDecode":
                            src.ReadByte();
                            src.ReadByte();
                            src = new DeflateStream(src, CompressionMode.Decompress);
                            break;
                    }

                return src;
            }
        }

        public byte[] DecodedData
        {
            get
            {
                var stream = DecodedStream;
                var buffer = new MemoryStream();
                stream.CopyTo(buffer);
                return buffer.ToArray();
            }
        }

        public string DecodedString
        {
            get
            {
                using (var sr = new StreamReader(DecodedStream, Encoding.Default))
                    return sr.ReadToEnd();
            }
        }
    }
}
